package com.qhnu.zxjx.interceptor;

import com.qhnu.zxjx.enums.SystemCodeEnum;
import com.qhnu.zxjx.exception.CustomException;
import com.qhnu.zxjx.exception.ValidatorException;
import com.qhnu.zxjx.model.response.Response;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

/**
 * @description: 统一异常处理
 * @author: panpei
 * @date: 2019/11/13 13:38
 * @version: 1.0
 **/
@RestControllerAdvice
public class ControllerInterceptor {
	private final Logger logger = LogManager.getLogger(getClass());

	/**
	 * 统一异常处理
	 * 
	 * @param exception
	 * @return
	 */
	@ExceptionHandler(value = { Exception.class })
	public Response validatorExceptionHandler(Exception exception) {
		logger.error("统一异常处理:", exception);
		exception.printStackTrace();
		List<String> errors = new ArrayList<String>();
		if (exception instanceof BindException) {
			BindException exs = (BindException) exception;
			dealErrors(errors, exs.getBindingResult());
			return new Response(SystemCodeEnum.ERROR_VALIDATOR_PARAMETER.getCode(), ArrayUtils.toString(errors));
		} else if (exception instanceof MethodArgumentNotValidException) {
			MethodArgumentNotValidException exs = (MethodArgumentNotValidException) exception;
			dealErrors(errors, exs.getBindingResult());
			return new Response(SystemCodeEnum.ERROR_VALIDATOR_PARAMETER.getCode(), ArrayUtils.toString(errors));
		} else if (exception instanceof ValidatorException) {
			ValidatorException ex = (ValidatorException) exception;
			return new Response(ex.getCode(), ex.getMessage());
		} else if (exception instanceof CustomException) {
			CustomException ex = (CustomException) exception;
			return new Response(ex.getCode(), ex.getMessage());
		} else if (exception instanceof ConstraintViolationException) {
			ConstraintViolationException ex = (ConstraintViolationException) exception;
			ex.getConstraintViolations().forEach(obj -> {
				errors.add(obj.getMessage());
			});
			return new Response(SystemCodeEnum.ERROR_VALIDATOR_PARAMETER.getCode(), ArrayUtils.toString(errors));
		} else {
			return new Response(SystemCodeEnum.ERROR_SERVER.getCode(), exception.getMessage());
		}
	}

	private void dealErrors(List<String> errors, BindingResult bindingResult) {
		List<FieldError> fieldErrors = bindingResult.getFieldErrors();
		if (!CollectionUtils.isEmpty(fieldErrors)) {
			fieldErrors.forEach(fieldError -> {
				errors.add(fieldError.getDefaultMessage());
			});
		}
	}

}